﻿using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Inovout.Data.Domain;

namespace System.Web.Mvc
{
    public class OrderCriteriaColllectionBuilder<TModel> : IEnumerable<OrderCriteria>
    {
        public OrderCriteriaColllectionBuilder(IEnumerable<OrderCriteria> orders = null)
        {
            this.Orders = new List<OrderCriteria>();
            if (orders != null)
            {
                this.Orders.AddRange(orders);
            }
        }

        public List<OrderCriteria> Orders { get; private set; }

        public OrderCriteriaColllectionBuilder<TEntity> OfType<TEntity>()
        {
            return new OrderCriteriaColllectionBuilder<TEntity>();
        }

        public OrderCriteriaColllectionBuilder<TModel> OrderFor<TProperty>(Expression<Func<TModel, TProperty>> orderPropertyNameExpression, bool ascending = true)
        {
            this.Orders.Add(new OrderCriteria(GetPropertyName(orderPropertyNameExpression), ascending));
            return this;
        }
        public OrderCriteriaColllectionBuilder<TModel> OrderDescendingFor<TProperty>(Expression<Func<TModel, TProperty>> orderPropertyNameExpression)
        {
            return OrderFor(orderPropertyNameExpression, false);
        }
        private string GetPropertyName<TProperty>(Expression<Func<TModel, TProperty>> propertyNameExpression)
        {
            string propertyName = ExpressionHelper.GetExpressionText(propertyNameExpression);
            if (typeof(DataObject).IsAssignableFrom(typeof(TProperty)))
            {
                propertyName += ".Id";
            }
            return propertyName;
        }
        public OrderCriteriaColllectionBuilder<TModel> Merge(IEnumerable<OrderCriteria> orders)
        {
            if (orders != null)
            {
                //todo 先暂时解决只有一个排序，却生成了与Filter一样的数组数量。
                orders = orders.Where(o=>!string.IsNullOrEmpty(o.OrderName));
                foreach (var order in orders)
                {
                    var buildOrder = this.Orders.SingleOrDefault(o => o.OrderName.Equals(order.OrderName));
                    if (buildOrder == null)
                    {
                        this.Orders.Add(order);
                    }
                    else
                    {
                        buildOrder.OrderAscending = order.OrderAscending;
                    }
                }
            }
            return this;

        }


        public IEnumerator<OrderCriteria> GetEnumerator()
        {
            return this.Orders.GetEnumerator();
        }

        Collections.IEnumerator Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }

}
